/*
Abstract:
  Logging implementation

Last changed:
  $Id: logging.cpp 82 2009-12-08 20:53:44Z vitamin.caig $

Author:
  (C) Vitamin/CAIG/2001

  This file is the part of Textator project
*/

#include "logging.h"

#include <tools.h>
#include <error.h>

#include <iostream>

#include <text.h>

namespace
{
  //singleton
  class LogHolder
  {
    LogHolder() : LogLevel(Log::DEFAULT)
    {
    }
    ~LogHolder()
    {
    }
  public:
    static LogHolder& Instance()
    {
      if (!Object)
      {
        Object = new LogHolder;
      }
      return *Object;
    }

    void SetLogLevel(Log::Level level)
    {
      LogLevel = level;
    }

    bool CheckLogLevel(Log::Level level)
    {
      return LogLevel >= level;
    }

    void MessageNL(const String& msg) const
    {
      StdErr << msg << std::endl;
    }
    void Message(const String& msg) const
    {
      StdErr << msg;
    }

  private:
    static LogHolder* Object;

  private:
    Log::Level LogLevel;
  };

  LogHolder* LogHolder::Object = 0;
}

namespace Log
{
  void SetLogLevel(Level level)
  {
    LogHolder::Instance().SetLogLevel(level);
  }

  bool CheckLogLevel(Level level)
  {
    return LogHolder::Instance().CheckLogLevel(level);
  }

  void DoMessage(const String& msg)
  {
    LogHolder::Instance().MessageNL(msg);
  }

  void ProgressMessage(std::size_t current, std::size_t total, Level level /* = VERBOSE */)
  {
    if (CheckLogLevel(level))
    {
      LogHolder::Instance().Message(
        Formatter<String>::Process(TEXT_FORMAT_PROGRESS, unsigned(100.0 * current / (total ? total : 1)))
        );
    }
  }

  void ErrorMessage(const Error& err)
  {
    Message(err.Text, DEFAULT);
    const Error::Detail& dtl(err.Dtl);
#ifndef NDEBUG
    Message(TEXT_FORMAT_ERROR_DBG, FromStdString(dtl.File), dtl.Line, FromStdString(dtl.Function), Hex(dtl.Tag), VERBOSE);
#else
    Message(TEXT_FORMAT_ERROR_RLS, Hex(dtl), VERBOSE);
#endif
  }
}
